<template>
  <div class="vuln-container">
    <div class="page-header">
      <div class="left">
        <h2>漏洞管理</h2>
      </div>
      <div class="right">
        <el-button type="primary" @click="handleAddVuln">添加漏洞</el-button>
        <el-button type="success" @click="handleImportVuln">批量导入</el-button>
        <el-button 
          type="danger" 
          @click="handleBatchDelete" 
          :disabled="selectedVulns.length === 0"
        >批量删除</el-button>
      </div>
    </div>

    <!-- 搜索过滤 -->
    <el-card class="filter-container">
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="关键词">
          <el-input v-model="searchForm.keyword" placeholder="标题或CVE编号"></el-input>
        </el-form-item>
        <el-form-item label="严重程度">
          <el-select v-model="searchForm.severity" placeholder="所有级别" clearable>
            <el-option label="严重" value="critical"></el-option>
            <el-option label="高危" value="high"></el-option>
            <el-option label="中危" value="medium"></el-option>
            <el-option label="低危" value="low"></el-option>
            <el-option label="信息" value="info"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="所有状态" clearable>
            <el-option label="新发现" value="new"></el-option>
            <el-option label="已验证" value="verified"></el-option>
            <el-option label="处理中" value="in_progress"></el-option>
            <el-option label="已修复" value="fixed"></el-option>
            <el-option label="已关闭" value="closed"></el-option>
            <el-option label="误报" value="false_positive"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 漏洞列表 -->
    <el-card>
      <el-table 
        :data="vulnList" 
        v-loading="loading" 
        border 
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="title" label="标题" min-width="200">
          <template #default="scope">
            <router-link :to="`/vulnerabilities/${scope.row.id}`" class="link-type">
              {{ scope.row.title }}
            </router-link>
          </template>
        </el-table-column>
        <el-table-column prop="cve_id" label="CVE编号" width="120"></el-table-column>
        <el-table-column prop="severity" label="严重程度" width="100">
          <template #default="scope">
            <el-tag :type="getSeverityType(scope.row.severity)" effect="dark">
              {{ getSeverityText(scope.row.severity) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="assets" label="资产" min-width="160">
          <template #default="scope">
            <div v-if="scope.row.assets && scope.row.assets.length">
              <el-tag v-for="(asset, index) in scope.row.assets" :key="index" 
                      type="info" class="asset-tag" effect="plain">
                {{ asset.name }}
              </el-tag>
            </div>
            <span v-else class="no-data">暂无数据</span>
          </template>
        </el-table-column>
        <el-table-column label="发现时间" width="160">
          <template #default="scope">
            {{ formatTime(scope.row.discovered_at) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" fixed="right">
          <template #default="scope">
            <div class="operation-buttons">
              <el-button type="primary" size="small" @click="handleEdit(scope.row)">
                <el-icon><Edit /></el-icon>
                <span>编辑</span>
              </el-button>
              <el-button type="danger" size="small" @click="handleDelete(scope.row)">
                <el-icon><Delete /></el-icon>
                <span>删除</span>
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          background
          :current-page="currentPage"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
    
    <!-- 导入对话框 -->
    <el-dialog v-model="importDialogVisible" title="导入漏洞" width="500px">
      <div class="import-dialog-content">
        <el-alert
          title="请按照模板格式导入漏洞数据，确保数据格式正确"
          type="info"
          :closable="false"
          show-icon
        />
        <el-alert
          style="margin-top: 10px;"
          title="注意：导入数据将覆盖已有相同标识的漏洞记录"
          type="warning"
          :closable="false"
          show-icon
        />
        <div class="upload-container">
          <el-upload
            class="upload-demo"
            drag
            action=""
            :http-request="uploadFile"
            :limit="1"
            :on-exceed="handleExceed"
            :on-remove="handleRemove"
            :auto-upload="false"
            :file-list="fileList"
            accept=".json,.csv"
            ref="uploadRef"
            :on-change="handleFileChange"
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
              拖拽文件到此处，或 <em>点击上传</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                支持 .json 或 .csv 格式文件
              </div>
            </template>
          </el-upload>
        </div>
        <div class="template-links">
          <el-link type="primary" href="/templates/vulnerabilities_template.json" target="_blank">下载JSON模板</el-link>
          <el-link type="primary" href="/templates/vulnerabilities_template.csv" target="_blank">下载CSV模板</el-link>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="importDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitUpload" :loading="importing">
            导入
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { reactive, ref, onMounted, toRefs } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessageBox, ElMessage } from 'element-plus'
import { UploadFilled, Edit, Delete } from '@element-plus/icons-vue'
import { listVulnerabilities, deleteVulnerability, batchImportVulnerabilities, batchDeleteVulnerabilities } from '@/api/vulnerability'
import { formatTime } from '@/utils/time'
import { getToken } from '@/utils/auth'

export default {
  name: 'VulnerabilityList',
  components: {
    UploadFilled,
    Edit,
    Delete
  },
  setup() {
    const router = useRouter()
    const loading = ref(false)
    const total = ref(0)
    const pageSize = ref(10)
    const currentPage = ref(1)
    const importDialogVisible = ref(false)
    const importing = ref(false)
    const uploadRef = ref(null)
    const fileList = ref([])
    const vulnList = ref([])
    const selectedVulns = ref([])
    
    const queryParams = reactive({
      page: 1,
      pageSize: 10,
      keyword: '',
      severity: '',
      status: ''
    })

    const state = reactive({
      searchForm: {
        keyword: '',
        severity: '',
        status: ''
      }
    })

    // 获取漏洞列表
    const getVulnList = async () => {
      loading.value = true
      try {
        const params = {
          page: currentPage.value,
          size: pageSize.value,
          keyword: state.searchForm.keyword,
          severity: state.searchForm.severity,
          status: state.searchForm.status
        }
        const res = await listVulnerabilities(params)
        vulnList.value = res.data.items
        total.value = res.data.total
      } catch (error) {
        console.error('获取漏洞列表失败', error)
        ElMessage.error('获取漏洞列表失败')
      } finally {
        loading.value = false
      }
    }

    // 获取严重性类型的颜色
    const getSeverityType = (severity) => {
      const typeMap = {
        critical: 'danger',
        high: 'danger',
        medium: 'warning',
        low: 'success',
        info: 'info'
      }
      return typeMap[severity] || 'info'
    }
    
    // 获取严重性对应的中文文本
    const getSeverityText = (severity) => {
      const textMap = {
        critical: '严重',
        high: '高危',
        medium: '中危',
        low: '低危',
        info: '信息'
      }
      return textMap[severity] || severity
    }

    // 获取状态类型颜色
    const getStatusType = (status) => {
      const typeMap = {
        new: 'danger',
        verified: 'warning',
        in_progress: 'primary',
        fixed: 'success',
        closed: 'info',
        false_positive: ''
      }
      return typeMap[status] || ''
    }
    
    // 获取状态对应的中文文本
    const getStatusText = (status) => {
      const textMap = {
        new: '新发现',
        verified: '已验证',
        in_progress: '处理中',
        fixed: '已修复',
        closed: '已关闭',
        false_positive: '误报'
      }
      return textMap[status] || status
    }

    // 处理添加漏洞
    const handleAddVuln = () => {
      router.push('/vulnerabilities/add')
    }

    // 处理编辑漏洞
    const handleEdit = (row) => {
      router.push(`/vulnerabilities/${row.id}`)
    }

    // 处理删除漏洞
    const handleDelete = (row) => {
      ElMessageBox.confirm(
        `确定要删除漏洞 "${row.title}" 吗？`,
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(async () => {
        try {
          await deleteVulnerability(row.id)
          ElMessage.success('删除成功')
          getVulnList()
        } catch (error) {
          console.error('删除漏洞失败', error)
          ElMessage.error('删除漏洞失败')
        }
      }).catch(() => {})
    }

    // 搜索
    const handleSearch = () => {
      currentPage.value = 1
      getVulnList()
    }

    // 重置
    const handleReset = () => {
      state.searchForm.keyword = ''
      state.searchForm.severity = ''
      state.searchForm.status = ''
      handleSearch()
    }

    // 处理导入漏洞
    const handleImportVuln = () => {
      importDialogVisible.value = true
      fileList.value = []
    }

    // 处理文件超过限制
    const handleExceed = () => {
      ElMessage.warning('只能上传一个文件')
    }

    // 处理文件移除
    const handleRemove = () => {
      fileList.value = []
    }

    // 处理文件变化
    const handleFileChange = (file) => {
      fileList.value = [file]
    }

    // 上传文件
    const uploadFile = async (options) => {
      const { file } = options
      const formData = new FormData()
      formData.append('file', file)
      
      try {
        importing.value = true
        const res = await batchImportVulnerabilities(formData)
        ElMessage.success(`成功导入 ${res.data.imported} 条记录`)
        importDialogVisible.value = false
        getVulnList()
      } catch (error) {
        console.error('导入漏洞失败', error)
        ElMessage.error(error.response?.data?.message || '导入漏洞失败')
      } finally {
        importing.value = false
      }
    }

    // 提交上传
    const submitUpload = () => {
      if (fileList.value.length === 0) {
        ElMessage.warning('请先选择文件')
        return
      }
      uploadRef.value.submit()
    }

    // 处理分页大小变化
    const handleSizeChange = (size) => {
      pageSize.value = size
      getVulnList()
    }

    // 处理当前页变化
    const handleCurrentChange = (page) => {
      currentPage.value = page
      getVulnList()
    }

    // 处理选择变化
    const handleSelectionChange = (selected) => {
      // 检查所选项是否包含ID
      if (selected.length > 0 && !selected[0].id) {
        console.error('选中的数据没有id属性:', selected)
        ElMessage.warning('选中的数据缺少必要的标识符')
        return
      }
      
      // 确保数组中的每一项都是数字ID
      selectedVulns.value = selected.map(item => {
        const id = Number(item.id)
        if (isNaN(id)) {
          console.error('无效的ID格式:', item.id, '原始对象:', item)
          return null
        }
        return id
      }).filter(id => id !== null)
      
      console.log('选中的漏洞IDs(处理后):', selectedVulns.value)
    }

    // 处理批量删除
    const handleBatchDelete = () => {
      if (selectedVulns.value.length === 0) {
        ElMessage.warning('请选择要删除的漏洞')
        return
      }

      const vulnNames = selectedVulns.value.length > 3 
        ? `${selectedVulns.value.length}个漏洞`
        : vulnList.value
            .filter(item => selectedVulns.value.includes(Number(item.id)))
            .map(item => item.title)
            .join('、')

      ElMessageBox.confirm(
        `确定要删除选中的${vulnNames}吗？此操作不可恢复。`,
        '批量删除确认',
        {
          confirmButtonText: '确定删除',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(async () => {
        try {
          console.log('准备批量删除漏洞，IDs:', selectedVulns.value)
          
          // 后端未实现批量删除API，使用循环调用单个删除API
          loading.value = true
          const total = selectedVulns.value.length
          let success = 0
          let failed = 0
          
          // 创建进度消息
          const progressMsg = ElMessage({
            type: 'info',
            message: `正在删除漏洞 (0/${total})...`,
            duration: 0
          })
          
          // 逐个删除漏洞
          for (let i = 0; i < selectedVulns.value.length; i++) {
            const id = selectedVulns.value[i]
            try {
              await deleteVulnerability(id)
              success++
              // 更新进度消息
              progressMsg.message = `正在删除漏洞 (${i+1}/${total})...`
            } catch (err) {
              console.error(`删除漏洞ID ${id} 失败:`, err)
              failed++
            }
          }
          
          // 关闭进度消息
          progressMsg.close()
          
          if (success > 0) {
            ElMessage.success(`成功删除 ${success} 个漏洞${failed > 0 ? `，${failed} 个漏洞删除失败` : ''}`)
            // 刷新列表
            getVulnList()
          } else {
            ElMessage.error('所有漏洞删除失败')
          }
        } catch (error) {
          console.error('批量删除漏洞失败:', error)
          ElMessage.error('批量删除操作失败')
        } finally {
          loading.value = false
        }
      }).catch(() => {
        // 用户取消删除
      })
    }

    onMounted(() => {
      getVulnList()
    })

    return {
      ...toRefs(state),
      loading,
      total,
      pageSize,
      currentPage,
      importDialogVisible,
      importing,
      uploadRef,
      fileList,
      vulnList,
      selectedVulns,
      getSeverityType,
      getSeverityText,
      getStatusType,
      getStatusText,
      handleAddVuln,
      handleEdit,
      handleDelete,
      handleSearch,
      handleReset,
      handleImportVuln,
      handleExceed,
      handleRemove,
      handleFileChange,
      uploadFile,
      submitUpload,
      handleSizeChange,
      handleCurrentChange,
      formatTime,
      handleBatchDelete,
      handleSelectionChange
    }
  }
}
</script>

<style scoped>
.vuln-container {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0;
  font-size: 22px;
  color: #303133;
}

.filter-container {
  margin-bottom: 20px;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.link-type {
  color: #409EFF;
  text-decoration: none;
}

.link-type:hover {
  text-decoration: underline;
}

.asset-tag {
  margin-right: 5px;
  margin-bottom: 5px;
}

.no-data {
  color: #909399;
  font-size: 13px;
}

.import-dialog-content {
  padding: 10px 0;
}

.upload-container {
  margin: 20px 0;
}

.template-links {
  display: flex;
  justify-content: space-around;
  margin-top: 15px;
}

.operation-buttons {
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.operation-buttons .el-button {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 6px 10px;
}

.operation-buttons .el-icon {
  margin-right: 4px;
}
</style> 